//
//  PlayIn.m
//  playin
//
//  Created by playin on 2019/2/12.
//  Copyright © 2019年 playin. All rights reserved.
//

#import "PlayIn.h"
#import "PIHttpManager.h"
#import "PIUtil.h"
#import "PITouchView.h"
#import "PIVideoDecode.h"
#import "PIVideoDisplay.h"
#import "PlayInView.h"
#import "PIDeviceInfo.h"
#import "PIReport.h"
#import "PICheck.h"
#import "PIPlay.h"
#import "PICommon.h"

@interface PlayIn () <PIPlayDelegate>

@property (nonatomic, strong) PIPlay *play;
@property (nonatomic, copy) NSString *userId;
@property (nonatomic, copy) NSString *userType;
@property (nonatomic, copy) NSString *token;
@property (nonatomic, copy) NSString *deviceID;
@property (nonatomic, assign) double serverDuration;
@property (nonatomic, assign) int timeOut;
@property (nonatomic, assign) BOOL started;

@end

static PlayIn * _instance = nil;

@implementation PlayIn {
    
    dispatch_source_t _timeOutTimer;
}

#pragma mark - init

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}

+ (instancetype)sharedInstance {
    
    if (_instance == nil) {
        _instance = [super new];
    }
    return _instance;
}

- (id)copyWithZone:(NSZone *)zone {
    
    return _instance;
}

- (id)mutableCopyWithZone:(NSZone *)zone {
    
    return _instance;
}

- (void)startPlayWithUserId:(NSString *)userId
                   userType:(NSString *)userType {
    
    self.userId = userId;
    self.userType = userType;
    self.timeOut = 120;
    self.started = NO;
    [self startPlay];
}

- (void)startPlay {

    NSString *urlStr = [NSString stringWithFormat:@"http://3.112.73.171/adtiming/play"];
    NSMutableDictionary *playParams = [NSMutableDictionary new];
    [playParams setValue:self.userType forKey:@"login_type"];
    [playParams setValue:self.userId forKey:@"user_id"];
   
    __weak typeof(self) weakself = self;
    [PIHttpManager post:urlStr params:playParams success:^(NSDictionary * _Nonnull result) {
        NSLog(@"[PlayIn] play result: %@", result);
        dispatch_async(dispatch_get_main_queue(), ^{
            [weakself startWithParams:result];
        });
    } failure:^(NSDictionary * _Nonnull error) {
        NSLog(@"[PlayIn] play error: %@", error);
        NSString *eInfo = [error valueForKey:@"PIHttpManager"];
        [self startPlayErrorWithCode:PIErrorNetwork info:eInfo];
    }];
}

- (void)startWithParams:(NSDictionary *)params {
    
    id code = [params valueForKey:@"code"];
    if (![PIUtil validObj:code]) {
        [self startPlayErrorWithCode:PIErrorInner info:@"inner error"];
        return;
    }
    int code_value = [code intValue];
    if (code_value == 0) {
        NSDictionary *tmpParams = [params valueForKey:@"data"];
        NSString *streamHost = [tmpParams valueForKey:@"stream_server_ip"];
        NSString *token = [tmpParams valueForKey:@"token"];
        NSString *deviceID = [tmpParams valueForKey:@"device_id"];
        id portObj = [tmpParams valueForKey:@"stream_server_port"];
        id serverDurationObj = [tmpParams valueForKey:@"duration"];
        id orientationObj = [tmpParams valueForKey:@"orientation"];
        id osTypeObj = [tmpParams valueForKey:@"os_type"];
        id device_Wobj = [tmpParams valueForKey:@"device_width"];
        id device_Hobj = [tmpParams valueForKey:@"device_height"];
    
        if (![PIUtil validStr:streamHost] ||
            ![PIUtil validStr:token] ||
            ![PIUtil validObj:portObj] ||
            ![PIUtil validObj:serverDurationObj] ||
            ![PIUtil validObj:orientationObj] ||
            ![PIUtil validObj:osTypeObj] ||
            ![PIUtil validObj:device_Wobj] ||
            ![PIUtil validObj:device_Hobj] ||
            ![PIUtil validStr:deviceID]) {
            [self startPlayErrorWithCode:PIErrorInner info:@"inner error"];
            return;
        }
        CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
        CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
        self.play = [[PIPlay alloc] initWithFrame:CGRectMake(0, 0, screenWidth, screenHeight)];
        self.play.delegate = self;
        uint16_t port = (uint16_t)[portObj integerValue];
        self.serverDuration = [serverDurationObj intValue];
        self.token = token;
        self.deviceID = deviceID;
        int orientation = [orientationObj intValue];
        int osType = [osTypeObj intValue];
        
        [self.play startWithHost:streamHost port:port token:token duration:self.serverDuration orientation:orientation osType:osType gameInfo:tmpParams];

    } else {
        NSString *errStr = [params valueForKey:@"error"];
        [self startPlayErrorWithCode:PIErrorInner info:errStr];
    }
}

- (void)resetStatus {
    
    self.serverDuration = 0.0;
    self.started = NO;
}

- (void)stopPlay {
    
    [self.play stopPIPlay];
}

- (void)startPlayErrorWithCode:(PIError)code info:(NSString *)info {
    
    dispatch_async(dispatch_get_main_queue(), ^{
        NSMutableDictionary *params = [NSMutableDictionary new];
        NSNumber *codeNum = [NSNumber numberWithInteger:code];
        [params setValue:codeNum forKey:@"code"];
        
        self.playInView.hidden = YES;
        NSString *errStr = [NSString stringWithFormat:@"%@", info];
        [params setValue:errStr forKey:@"info"];
        
        if (self.delegate && [self.delegate respondsToSelector:@selector(onPlayInError:)]) {
            [self.delegate onPlayInError: params];
        }
    });
}

#pragma mark - PIPlayDelegate

- (void)onPIPlayError:(NSString *)error {
    
    [self startPlayErrorWithCode:PIErrorResource info:error];
}

- (void)onPIPlayStarted {
    
    self.playInView = self.play.playInView;
    self.playInView.hidden = NO;
    if (self.delegate && [self.delegate respondsToSelector:@selector(onPlayInStart:)]) {
        [self.delegate onPlayInStart:self.serverDuration];
    }
}

- (void)onPIPlaySocketEnd {
 
    NSNumber *idrCount = [NSNumber numberWithInt:self.play.receiveIDRCount];
    NSNumber *gesCount = [NSNumber numberWithInt:self.play.sendGestureCount];
    
    [PIReport reportWithDeviceID:self.deviceID token:self.token idrCount:idrCount gesCount:gesCount];
    if (self.delegate && [self.delegate respondsToSelector:@selector(onPlayInStop)]) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.delegate onPlayInStop];
        });
    }
}

- (void)dealloc {
    
    NSLog(@"***** [%@ dealloc] *****", [self class]);
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

@end


/** dealloc
PlayIn              ok
PIPlay              ok
PIConfigure         ok
PIDownloadView      ok
PIGameView          ok
PIGCDAsyncSocket    ok
PIPing              ok
PIPingHelper        ok
PISocketManager     ok
PITouchView         ok
PIVideoDisplay      ok
PlayInView          ok
**/
